using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace Framework
{
    using System.Runtime.CompilerServices;
    using Table;
    public class TableManager
    {
        static TableManager Instance = new TableManager();
        Dictionary<System.Type, ITable> mTables = new Dictionary<System.Type, ITable>(128);
        const string fmtString = "{0}";
        public static bool Performance = false;
        static YooAsset.ResourcePackage resourcePackage;

        public static void Initialze(string packageName = "DefaultPackage")
        {
            Clear();
            resourcePackage = YooAsset.YooAssets.GetPackage(packageName);
        }

        public static void Clear()
        {
            Instance.ClearInternal();
        }

        public static void LoadTable<T>() where T : class, ITable, new()
        {
            if(Performance)
            {
                UnityEngine.Profiling.Profiler.BeginSample("LoadTableInternal");
                Instance.LoadTableInternal<T>();
                UnityEngine.Profiling.Profiler.EndSample();
            }
            else
                Instance.LoadTableInternal<T>();
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static T GetTable<T>() where T : class, ITable, new()
        {
            return Instance.GetTableInternal<T>();
        }

        void ClearInternal()
        {
            foreach(var t in mTables.Values)
            {
                t.UnLoad();
            }
            mTables.Clear();
        }

        void LoadTableInternal<T>() where T : class,ITable,new()
        {
            System.Type type = typeof(T);
            if(mTables.ContainsKey(type))
            {
                SLogger.E($"[TableManager]:Table Has Already Loaded For {type.Name}");
                return;
            }

            var assetValue = string.Format(fmtString, type.Name);
            var tableAsset = resourcePackage.LoadAssetSync(assetValue, typeof(TextAsset));
            if(null == tableAsset || !string.IsNullOrEmpty(tableAsset.LastError))
            {
                SLogger.E($"[TableManager]:Load Table Failed For {type.Name}");
                return;
            }

            T inst = new T();
            inst.Load((tableAsset.AssetObject as TextAsset).bytes);
            tableAsset.Release();

            mTables.Add(type, inst);
        }

        T GetTableInternal<T>() where T : class, ITable, new()
        {
            System.Type type = typeof(T);
            if (!mTables.ContainsKey(type))
            {
                SLogger.E($"[TableManager]:Table Has Not Loaded Yet For {type.Name}");
                return default(T);
            }
            return (T)mTables[type];
        }
    }
}